iT邦幫忙

2023 iThome 鐵人賽

DAY 15
0
自我挑戰組

寫給自己看的前端學習筆記系列 第 15

寫給自己看的前端學習筆記 Day15

  • 分享至 

  • xImage
  •  

鐵人賽 Day 15

tags: 鐵人賽

既然是 single thread 怎麼會非同步?

單執行緒的意思就是一次只能處理一件事情,怎麼會有執行程式不阻塞的可能?
這時就會介紹到 Event Loop 這個非同步概念裡的重要角色。

Event Loop

Event Loop示意圖

https://ithelp.ithome.com.tw/upload/images/20230930/20127971Als26QKPHt.png

就如上圖 JS 裡的 stack 的執行程序確實只能一次執行一個,當遇到非同步的執行任務如 setTimeout 就會使用 請 WebAPI 設定計時,等到計時結束
callback function 會排到 callback queue 裡面依續排隊。

Event Loop 的功用非常的簡單,當今天 stack 上面沒有任何執行任務,
就把 callback queue 最先排隊的任務傳到 stack 執行。

這個機制也解釋了為什麼 setTimeout 的時間參數即使設定為 0 毫秒也不會立即執行 callback function 。

console.log('start');

(function(){
  console.log('apply function')
  
  window.setTimeout(function(){
    console.log('pick me first');
  },0)

})()

console.log('end');

// cosole 結果

"start"
"apply function"
"end"
"pick me first"

閉包 closure

閉包的概念可以理解成讓變數鎖在特定的作用域裡面,只有 function 內部可以使用,就像是物件有 private 方法。

不使用閉包的狀況雖然可以使用全域變數,但會造成變數污染,兩個 function 都用到相同的變數產生預期外的 bug。

只有一組 function 的情況

var count = 0

function countSheep(){
    count +=1;
    console.log(count+'sheep');
}

countSheep(); 
countSheep();
countSheep();

//1sheep
//2sheep
//3sheep

使用兩組 function 後變數污染

var count = 0

function countSheep(){
    count +=1;
    console.log(count+'sheep');
}

countSheep();
countSheep();
countSheep();


function countCat(){
    count +=1;
    console.log(count+'cat');
}
countCat();
countCat();
countCat();
countSheep();

// 輸出結果
"1sheep"
"2sheep"
"3sheep"
"4cat"
"5cat"
"6cat"
"7sheep"

應家要有兩個獨立的計數器,因為使用全域變數而混在一起了。

使用閉包的情況

function farm(){
    var count = 0;
    function countSheep(){
        count+=1;
        console.log(count+'sheep');
    }
    return countSheep;
}

const countSheep = farm()

countSheep();
countSheep();

// 輸出結果
"1sheep"
"2sheep"

透過外層 function 回傳內層 function的方式,可以取得當時定義 function 內的變數,記住當時的環境變數就是閉包。

補充
由於外層 function 回傳另一個在內部的 function,所以透過指定給變數再呼叫內部 function 本身才會取得我們要的值。

function farm(){
    var count = 0;
    function countSheep(){
        count+=1;
        console.log(count+'sheep');
    }
    return countSheep;
}
const countSheep = farm()
console.log(countSheep);
// 輸出結果
function countSheep(){
      count+=1;
      window.runnerWindow.proxyConsole.log(count+'sheep');
  }

上一篇
寫給自己看的前端學習筆記 Day14
下一篇
寫給自己看的前端學習筆記 Day16
系列文
寫給自己看的前端學習筆記18
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言